#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include<iostream>
using namespace std;

//只能在堆上创建对象==>不能通过拷贝创建对象
class HeapOnly
{
public:
	static HeapOnly* GetHeapOnly()
	{
		return new HeapOnly();
	}
private:
	HeapOnly() = default;
	HeapOnly(const HeapOnly&) = delete;
	HeapOnly& operator=(const HeapOnly&) = delete;
};

//只能在栈上创建对象==>不能通过new/new[] 创建对象
class StackOnly
{
public:
	static StackOnly  GetStackOnly()
	{
		StackOnly s;
		return s; //传值返回，调用的是拷贝构造/移动构造，所以拷贝构造不能禁用
	}
private:
	StackOnly(){}
	void* operator new(size_t size) = delete;
	void* operator new[](size_t size) = delete;
	void operator delete(void* p) = delete;
};

//设计一个类不能发生拷贝
class NonCopy
{
public:
	NonCopy(){}
private:
	NonCopy(const NonCopy&) = delete;
	NonCopy& operator=(const NonCopy&) = delete;
};
//设计一个类不能被继承
//C++98：将父类构造函数私有化 ==>不够彻底，子类仍然可以继承父类，只是没办法实例化出对象
//C++11: 被final修饰的类称为最终类，不能被继承
class NonHeir final //C++11
{
private:
	//NonHeir() {}  //C++98
};

//饿汉模式
//class SingLeton
//{
//public:
//	static SingLeton& GetInstance()
//	{
//		return inst;
//	}
//private:
//	SingLeton(){}
//	SingLeton(const SingLeton&) = delete;
//	SingLeton& operator=(const SingLeton&) = delete;
//
//	static SingLeton inst;
//};
//SingLeton SingLeton::inst;


#include<mutex>
class SingLeton
{
public:
	static volatile SingLeton* GetInstance()
	{
		if (inst == nullptr)
		{
			unique_lock<mutex> uq(mtx);
			if (inst == nullptr)
			{
				inst = new SingLeton();
			}
		}
		return inst;
	}
private:
	SingLeton() {}
	SingLeton(const SingLeton&) = delete;
	SingLeton& operator=(const SingLeton&) = delete;
	
	volatile static SingLeton* inst;
	static mutex mtx;
};
volatile SingLeton* SingLeton::inst = nullptr;
mutex SingLeton::mtx;

int main()
{
	NonCopy a;
	NonCopy b;
	//HeapOnly* hp = HeapOnly::GetHeapOnly();
	/*StackOnly a = StackOnly::GetStackOnly();
	StackOnly b = StackOnly::GetStackOnly();
	cout << &a << " " << &b << endl;*/
	//StackOnly* sp = new StackOnly(a);
	return 0;
}